#ifndef __CLIENT_COMMON_TABLE_included
#define __CLIENT_COMMON_TABLE_included

#include <boost/shared_array.hpp>

namespace Client {
namespace Common {

class CRecord;

class CTableTrigger {

public :
	virtual void OnAdded(RecordRef r) = 0;
	virtual void OnDeleted(RecordRef r) = 0;
	virtual void OnUpdated(RecordRef r) = 0;
};

typedef boost::shared_ptr<CTableTrigger> TableTriggerRef;

class CTable {

	
	int mLastReadRange[2];

protected :

	int mCount;
	boost::shared_array<RecordRef> mCurrentRecords;

	void CalcNextRecordsIndex(int n, int& first, int& last) {
	
		if(mLastReadRange[1] == -1) {
			first = 0;
		}
		else {
			first = mLastReadRange[1] + 1;
		}
		
		if(n == -1) {
			last = mCount - 1;
		}
		else {
			if(first + n > mCount) n = mCount - first;
			last = first + n - 1;
		}
	}

	void CalcPrevRecordsIndex(int n, int& first, int& last) {
		
		if(mLastReadRange[0] <= 0) {
			first = last = -1;
			return;
		}
		
		if(n > mLastReadRange[0]) n = mLastReadRange[0];
		first = mLastReadRange[0] - n;
		last = mLastReadRange[0] - 1;

	}

	void CommitRecordsIndex(int first, int last) {
		mLastReadRange[0] = first;
		mLastReadRange[1] = last;
	}

public :

	CTable() : mCount(0) { Reset(); }
	CTable(int count) : mCount(count) { Reset(); }
	~CTable() { }

	int GetCount() { return mCount; }
	int GetCurrentRecordsCount() { return mLastReadRange[1] - mLastReadRange[0] + 1; }
	boost::shared_array<RecordRef>& CurrentRecords() { return mCurrentRecords; }
	void Reset() { mLastReadRange[0] = mLastReadRange[1] = -1; }
	int GetPos() { return mLastReadRange[0]; }
	
	void SetNextPos(int pos) {
		if(pos < 0) return;
		mLastReadRange[1] = pos-1;
	}

	virtual void Add(RecordRef r) = 0;
	virtual void Close() = 0;
	virtual boost::shared_array<RecordRef>& NextRecords(int n) = 0;
	virtual string& ToString() = 0;
};

typedef boost::shared_ptr<CTable> TableRef;

} // Common
} // Client

#endif //__CLIENT_COMMON_TABLE_included
